﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using CityGateway.Objects;
using System.IO;


namespace CityGamePlay
{
    public class Life
    {
        public static Dictionary<long, Dictionary<int, int>> Evacs = new Dictionary<long, Dictionary<int, int>>();


        public delegate void OnEvac(long userid, Dictionary<int, int> evacs);
        public event OnEvac Evac;


        public delegate void OnImmigrate(long userid, Dictionary<int, int> immigrants);
        public event OnImmigrate Immigrate;



        public static Cities Cities { get; set; }

        public Timer LifePulse;

   


        public int SaveInterval = 10;
        private int SaveIntervalCounter;



        private int m_LifeInterval = 2000;//  3600000;  //stands for 1 hour, each hour advances the simulation by a month;

        public int LifeHourInterval =2000;// 3600000;



        public int LifeInterval
        {
            get
            {
                return m_LifeInterval;
            }
            set
            {
                LifePulse.Stop();
                m_LifeInterval = value;
                LifePulse.Interval = value;
                LifePulse.Elapsed += new ElapsedEventHandler(LifePulse_Elapsed);
                LifePulse.Start();
            }
        }





        public Life()
        {
            Cities = new Cities();
            Cities.LoadCities();

            LifePulse = new Timer();
            LifePulse.Interval = LifeInterval;
            LifePulse.Elapsed += new ElapsedEventHandler(LifePulse_Elapsed);
            LifePulse.Start();
           // HandleLife();
        }


   



        void AdjustPopulation()
        {



         //clear the     Evacs[city.UserID]
            foreach (long userid in Evacs.Keys)
            {
                if (Evac != null)
                    Evac(userid, Evacs[userid]);

                //immigration can travels to neibougrs only
                //so get the neibours list
                List<City> neigbours = (from n in Cities.Values
                                            where n.Neighboures.ContainsKey(userid)
                                            orderby n.CityStatus.CityScore.Score descending
                                            select n).ToList();

                int devider = neigbours.Count;
                Dictionary<int, int> years = Evacs[userid];
                foreach (City n in neigbours)
                {
                    Dictionary<int, int> incomings = new Dictionary<int, int>();
                    foreach (int year in years.Keys)
                    {
                        int yearcut = (int) Math.Ceiling((double) years[year] / devider);
                        incomings.Add(year, yearcut);
                        if (n.CityStatus.Population.PopulationByYears.ContainsKey(year))
                        n.CityStatus.Population.PopulationByYears[year] +=yearcut;
                        else
                            n.CityStatus.Population.PopulationByYears.Add(year, yearcut);

                    }

                    if (Immigrate != null)
                        Immigrate(n.UserID, incomings);
                }

          
            }


 
            Evacs = new Dictionary<long, Dictionary<int, int>>();
        }


        void HandleLife()
        {
            LifePulse.Enabled = false;
            foreach (City city in Cities.Values)
            {

                if (city.Budget.ToString() != "0")
                {
                    city.CityStatus.CityDate = city.CityStatus.CityDate.AddDays(30);
                    //calculate city rates


                    city.CityStatus.CalculateStatus(city);

                    Evacs[city.UserID] = city.CityStatus.AdjustNeedsAndPopulation(city);


                    city.CityStatus.CollectTax(city);

                    city.CityStatus.PayTheBills(city);

                }
               
            }


            AdjustPopulation();

 
            LifePulse.Enabled = true;

        }

        void LifePulse_Elapsed(object sender, ElapsedEventArgs e)
        {
            LifePulse.Stop();
            HandleLife();
          
            SaveIntervalCounter++;
            Cities.SaveCities();
            //Cities.LoadCities();
            LifePulse.Start();

            
            //if (SaveInterval == SaveIntervalCounter)
            //{
            //    SaveIntervalCounter = 0;
            //    Cities.SaveCities();
              

            //}

            //main timer life span



        }
    }
}
